﻿Imports System
Imports System.CodeDom
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.Text.RegularExpressions

Namespace System.Workflow.ComponentModel.Compiler
    Public NotInheritable Class AttributeInfo
        ' Methods
        Friend Sub New(ByVal attributeType As Type, ByVal argumentNames As String(), ByVal argumentValues As Object())
            Me.attributeType = attributeType
            Me.argumentNames = DirectCast(argumentNames.Clone, String())
            Me.argumentValues = DirectCast(argumentValues.Clone, Object())
        End Sub

        Public Function CreateAttribute() As Attribute
            If Not Me.Creatable Then
                Throw New InvalidOperationException(SR.GetString("CannotCreateAttribute"))
            End If
            Dim list As New List([Of] String)
            Dim list2 As New ArrayList
            Dim list3 As New ArrayList
            Dim i As Integer
            For i = 0 To Me.argumentNames.Length - 1
                If ((Me.argumentNames(i) Is Nothing) OrElse (Me.argumentNames(i).Length = 0)) Then
                    list3.Add(Me.argumentValues(i))
                Else
                    list.Add(Me.argumentNames(i))
                    list2.Add(Me.argumentValues(i))
                End If
            Next i
            Dim attribute As Attribute = DirectCast(Activator.CreateInstance(Me.attributeType, list3.ToArray), Attribute)
            Dim j As Integer
            For j = 0 To list.Count - 1
                Me.attributeType.GetProperty(list.Item(j)).SetValue(attribute, list2.Item(j), Nothing)
            Next j
            Return attribute
        End Function

        Public Function GetArgumentValueAs(ByVal serviceProvider As IServiceProvider, ByVal argumentIndex As Integer, ByVal requestedType As Type) As Object
            If ((argumentIndex >= Me.ArgumentValues.Count) OrElse (argumentIndex < 0)) Then
                Throw New ArgumentException(SR.GetString("Error_InvalidArgumentIndex"), "argumentIndex")
            End If
            If (requestedType Is Nothing) Then
                Throw New ArgumentNullException("requestedType")
            End If
            Dim supportedLanguage As SupportedLanguages = CompilerHelpers.GetSupportedLanguage(serviceProvider)
            If (requestedType Is GetType(String)) Then
                Dim str As String = [TryCast](Me.ArgumentValues.Item(argumentIndex),String)
                If (Not str Is Nothing) Then
                    Try 
                        str = Regex.Unescape(str)
                    Catch obj1 As Object
                    End Try
                End If
                If (Not str Is Nothing) Then
                    If str.EndsWith("""", StringComparison.Ordinal) Then
                        str = str.Substring(0, (str.Length - 1))
                    End If
                    If ((supportedLanguage = SupportedLanguages.CSharp) AndAlso str.StartsWith("@""", StringComparison.Ordinal)) Then
                        Return str.Substring(2, (str.Length - 2))
                    End If
                    If str.StartsWith("""", StringComparison.Ordinal) Then
                        str = str.Substring(1, (str.Length - 1))
                    End If
                End If
                Return str
            End If
            If requestedType.IsEnum Then
                Dim str2 As String = ""
                Dim flag As Boolean = True
                Dim str3 As String
                For Each str3 In [TryCast](Me.ArgumentValues.Item(argumentIndex),String).Split(New String() { If((supportedLanguage = SupportedLanguages.CSharp), "|", "Or") }, StringSplitOptions.RemoveEmptyEntries)
                    If Not flag Then
                        str2 = (str2 & ",")
                    End If
                    Dim num As Integer = str3.LastIndexOf("."c)
                    If (num <> -1) Then
                        str2 = (str2 & str3.Substring((num + 1)))
                    Else
                        str2 = (str2 & str3)
                    End If
                    flag = False
                Next
                Return Enum.Parse(requestedType, str2)
            End If
            If (requestedType Is GetType(Boolean)) Then
                Return Convert.ToBoolean(Me.ArgumentValues.Item(argumentIndex), CultureInfo.InvariantCulture)
            End If
            If (Not requestedType Is GetType(Type)) Then
                Return Nothing
            End If
            Dim typeName As String = ""
            If TypeOf Me.ArgumentValues.Item(argumentIndex) Is CodeTypeOfExpression Then
                typeName = DesignTimeType.GetTypeNameFromCodeTypeReference([TryCast](Me.ArgumentValues.Item(argumentIndex),CodeTypeOfExpression).Type, Nothing)
            End If
            Dim service As ITypeProvider = [TryCast](serviceProvider.GetService(GetType(ITypeProvider)),ITypeProvider)
            If (service Is Nothing) Then
                Throw New Exception(SR.GetString("General_MissingService", New Object() { GetType(ITypeProvider).ToString }))
            End If
            Dim type As Type = ParseHelpers.ParseTypeName(service, supportedLanguage, typeName)
            If (Not type Is Nothing) Then
                Return type
            End If
            Dim parameters As String() = Nothing
            Dim str5 As String = String.Empty
            Dim elemantDecorator As String = String.Empty
            If ((Not ParseHelpers.ParseTypeName(typeName, If((supportedLanguage = SupportedLanguages.CSharp), ParseTypeNameLanguage.CSharp, ParseTypeNameLanguage.VB), str5, parameters, elemantDecorator) OrElse (str5 Is Nothing)) OrElse (parameters Is Nothing)) Then
                Return type
            End If
            Dim str7 As String = (str5 & "`" & parameters.Length.ToString(CultureInfo.InvariantCulture) & "[")
            Dim str8 As String
            For Each str8 In parameters
                If (str8 <> parameters(0)) Then
                    str7 = (str7 & ",")
                End If
                Dim type2 As Type = ParseHelpers.ParseTypeName(service, supportedLanguage, str8)
                If (Not type2 Is Nothing) Then
                    str7 = (str7 & "[" & type2.FullName & "]")
                Else
                    str7 = (str7 & "[" & str8 & "]")
                End If
            Next
            str7 = (str7 & "]")
            Return ParseHelpers.ParseTypeName(service, supportedLanguage, str7)
        End Function


        ' Properties
        Public ReadOnly Property ArgumentValues As ReadOnlyCollection([Of] Object)
            Get
                Dim list As New List([Of] Object)(Me.argumentValues)
                Return list.AsReadOnly
            End Get
        End Property

        Public ReadOnly Property AttributeType As Type
            Get
                Return Me.attributeType
            End Get
        End Property

        Public ReadOnly Property Creatable As Boolean
            Get
                If (Me.attributeType.Assembly Is Nothing) Then
                    Return False
                End If
                Dim obj2 As Object
                For Each obj2 In Me.argumentValues
                    If TypeOf obj2 Is Exception Then
                        Return False
                    End If
                Next
                Return True
            End Get
        End Property


        ' Fields
        Private argumentNames As String()
        Private argumentValues As Object()
        Private attributeType As Type
    End Class
End Namespace

